const gifConvert = require('./jl_gifconvert_2.0.0-beta1.js');
// import { MessageConstant } from "../base/workTask";
const workTask = require('../base/workTask.js');

class GifConvertMessage {
    /**
     * 消息-Gif转换Bin
    */
    static MSG_GIF_CONVERT_BIN = "message_gif_convert_bin"
}
class Key {
    static FUNC = "func"

    /*****************************************输入参数*********************************/

    /**
     * 输入数据()
    */
    static IN_BUFFER = "in_buffer"
    /**
     * 芯片类型
     */
    static CHIP = "chip";
    /**
     *   质量模式
     */
    static MODE = "mode";
    /*****************************************输出结果参数*********************************/

    /**
    * 结果码
    * <p>
    * 说明:<br/>
    * 1. 小于等于0, 视为转码失败，负数为错误码<br/>
    * 2. 大于0，意味着转码成功
    * </p>
    */
    static RESULT = "result"
    /**
     * 输出数据
     */
    static OUTPUT_BUFFER = "output_buffer"
    /**
     * 宽度
     */
    static WIDTH = "width"
    /**
     * 高度
     */
    static HEIGHT = "height"
    /**
     * 消息
     */
    static MESSAGE = "message"

}

class Result {
    // 错误
    static ERR_ERROR = -1;
    // 成功
    static ERR_NONE = 0;
    // 无法打开给定的文件
    static ERR_OPEN_FILE = 1;
    // 写数据失败
    static ERR_WRITE_FAILED = 2;
    // 具有SCRN DSCR
    static ERR_HAS_SCRN_DSCR = 3;
    // 具有IMAG DSCR
    static ERR_HAS_IMAG_DSCR = 4;
    // 缺少颜色表
    static ERR_NO_COLOR_MAP = 5;
    // 数据太大
    static ERR_DATA_TOO_BIG = 6;
    // 内存不足
    static ERR_NOT_ENOUGH_MEM = 7;
    // 硬盘已满
    static ERR_DISK_IS_FULL = 8;
    // 关闭文件失败
    static ERR_CLOSE_FAILED = 9;
    // 没有写属性
    static ERR_NOT_WRITEABLE = 10;
    // 无法打开给定的文件
    static ERR_D_OPEN_FILE = 101;
    // 无法读取文件数据
    static ERR_READ_FAILED = 102;
    // 不是GIF文件
    static ERR_NOT_GIF_FILE = 103;
    // 没有SCRN DSCR
    static ERR_NO_SCRN_DSCR = 104;
    // 没有IMAG DSCR
    static ERR_NO_IMAG_DSCR = 105;
    // 没有颜色表
    static ERR_D_NO_COLOR_MAP = 106;
    // 错误记录
    static ERR_WRONG_RECORD = 107;
    // 数据太大
    static ERR_D_DATA_TOO_BIG = 108;
    // 空间不足
    static ERR_D_NOT_ENOUGH_MEM = 109;
    // 关闭文件失败
    static ERR_D_CLOSE_FAILED = 110;
    // 文件不可读
    static ERR_NOT_READABLE = 111;
    // 图像检测失败
    static ERR_IMAGE_DEFECT = 112;
    // 文件结束太快
    static ERR_EOF_TOO_SOON = 113;
    // 无效参数
    static ERR_INVALID_PARAM = 301;
    // 正在操作中
    static ERR_OP_IN_PROGRESS = 302;
    // 保存文件失败
    static ERR_SAVE_FILE = 303;
    // 未知的压缩模式
    static ERR_UNKNOWN_MODE = -128;
    // 未知的芯片类型
    static ERR_UNKNOWN_CHIP = -129;
}
var moduleIsInit = false;
function onError(errorCode) {
    const messageObj = new Object();
    messageObj[Key.FUNC] = workTask.MessageConstant.MSG_FINISHED;
    messageObj[Key.RESULT] = errorCode;
    worker.postMessage(messageObj);
}
function onStart() {
    const messageObj = new Object();
    messageObj[Key.FUNC] = workTask.MessageConstant.MSG_START;
    worker.postMessage(messageObj);
}
const inputFileName = "input_file.bin"
const outputFileName = "output_file.bin"
const utf8Decoder = new TextDecoder('utf-8');

function UTF8ToString(heap, ptr, maxLength = Infinity) {
    let end = ptr;
    while (heap[end] !== 0 && end < ptr + maxLength) {
        end++;
    }
    const array = new Uint8Array(heap.buffer, ptr, end - ptr);
    return utf8Decoder.decode(array);
}
worker.onMessage(function (msg) {
    // processing of workder
    console.log("worker.onMessage image convert", msg);
    if (!moduleIsInit) {
        moduleIsInit = gifConvert.Module.calledRun;        
    }
    const func = msg[Key.FUNC];
    if (func === workTask.MessageConstant.MSG_TERMINATE) {
        //结束当前worker
        console.log("当前worker 中止结束");
        onError(Result.ERR_ERROR)
    } else if (func === GifConvertMessage.MSG_GIF_CONVERT_BIN
    ) {
        const Module = gifConvert.Module;
        const inBuffer = msg[Key.IN_BUFFER];
        if (inBuffer === undefined) {
            console.log(" inBuffer is undefined");
            onError(Result.ERR_INVALID_PARAM)
            return;
        }

        const tempInBuffer = new Uint8Array(inBuffer);

        let runFunction = function () { }
        const resultFunction = function (result) {

            console.log('Conversion Result:', result);
            // console.log('Output Data:', outputData);
            // 通知 任务已结束了
            const messageObj = new Object();
            messageObj[Key.FUNC] = workTask.MessageConstant.MSG_FINISHED;
            messageObj[Key.RESULT] = result.code;
            // messageObj[Key.OUTPUT_BUFFER] = outputData?.buffer;
            messageObj[Key.MESSAGE] = result.message;
            messageObj[Key.OUTPUT_BUFFER] = result.data;
            messageObj[Key.WIDTH] = result.width;
            messageObj[Key.HEIGHT] = result.height;
            // 释放内存（如果需要）
            // module._free(ptrObj.inputPtr);
            worker.postMessage(messageObj);
        }
        if (func === GifConvertMessage.MSG_GIF_CONVERT_BIN) {
            console.log("worker.onMessage Gif转换Bin", msg);
            const mode = msg[Key.MODE];
            const chip = msg[Key.CHIP];
            runFunction = function () {
                onStart();
                // const ptrObj = initFunction()
                // 使用 Module.cwrap 导出函数
                const gifConvertBin = Module.cwrap(
                    'gif_convert_bin_result',
                    null, // 返回 void
                    ['string', 'number', 'number', 'number'] // 参数：inFilePath, mode, chip, outResultPtr
                );
                // const result = module._gif_convert_bin(ptrObj.inputPtr, mode, chip)
                const resultSize = 24; // sizeof(GifConvertResult) ≈ 24 bytes (假设 32-bit 指针)
                const resultPtr = Module._malloc(resultSize);
                // 调用 C 函数
                try {
                    gifConvertBin(inputFileName, mode, chip, resultPtr);
                    // 读取字段
                    const code = Module.HEAP32[resultPtr >> 2];

                    const messagePtr = Module.HEAP32[(resultPtr + 4) >> 2];

                    const gifBinNamePtr = Module.HEAP32[(resultPtr + 8) >> 2];
                    const gifBinWidth = Module.HEAP32[(resultPtr + 12) >> 2];
                    const gifBinHeight = Module.HEAP32[(resultPtr + 16) >> 2];
                    const gifBinSize = Module.HEAP32[(resultPtr + 20) >> 2];
                    const gifBinDataPtr = Module.HEAP32[(resultPtr + 24) >> 2];

                    // 转换字符串
                    const message = UTF8ToString(Module.HEAPU8, messagePtr);
                    const name = UTF8ToString(Module.HEAPU8, gifBinNamePtr);
                    console.log('Code:', code);
                    console.log('Message:', message);
                    console.log('Name:', name);
                    console.log('Width:', gifBinWidth);
                    console.log('Height:', gifBinHeight);
                    console.log('Size:', gifBinSize);

                    // 如果 data 是二进制数据
                    const dataArray = new Uint8Array(gifBinSize);
                    for (let i = 0; i < gifBinSize; i++) {
                        dataArray[i] = Module.HEAPU8[gifBinDataPtr + i];
                    }
                    console.log('Binary Data (first 16 bytes):', dataArray.slice(0, 16));

                    // 释放内存（注意：C 函数中必须 free 或手动管理）
                    Module._free(resultPtr);

                    resultFunction({
                        code: code,
                        message: message,
                        width: gifBinWidth,
                        height: gifBinHeight,
                        data: dataArray?.buffer
                    })
                } catch (error) {
                    console.warn("gifConvertBin has error", error)
                    resultFunction(Result.ERR_ERROR)
                }
            }
        }

        Module.onRuntimeInitialized = function () {
            // 初始化完成
            console.log("module.onRuntimeInitialized", Module);
            Module.FS.createDataFile('/', inputFileName, tempInBuffer, true, true);
            moduleIsInit = true;
            runFunction()
        }
        if (moduleIsInit) {
            Module.FS.createDataFile('/', inputFileName, tempInBuffer, true, true);
            runFunction()
        }
    }
})
